﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AMStudio.DelegateDispather;
using AMStudio.Script;
using AMStudio.Driver;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;


namespace AMStudio.Common
{
    public partial class GeneralManager
    {
        //protected bool MainPLCError = false;               
        protected void WritePLC(IAutomationDriver plc, string address, string value)
        {
            IExecuteReader result = plc.ExecuteReader("WRITE_STRINGVALUE", address, 1, value);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            //return result.Result;
        }
        protected void WritePLC(IAutomationDriver plc, string address, int length, object value)
        {
            IExecuteReader result = plc.ExecuteReader("WRITE", address, length, value);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            //return (T)result.Result;
        }

        protected void WritePLCAndLogProcess(IAutomationDriver plc, string address, int length, object value)
        {
            IExecuteReader result = plc.ExecuteReader("WRITE", address, length, value);
            if (result.Success)
            {
                string message = "Write Success," + address + ",length=" + length.ToString() + ",Value=" + value.ToString();
                LogEntry e = new LogEntry(message, "SimpleLog", 0, 0, System.Diagnostics.TraceEventType.Information, "", null);
                Logger.Write(e);
            }
            else
            {
                string message = "Write Fail," + address + ",length=" + length.ToString() + ",Value=" + value.ToString();
                LogEntry e = new LogEntry(message, "SimpleLog", 0, 0, System.Diagnostics.TraceEventType.Information, "", null);
                Logger.Write(e);
            }
            //return (T)result.Result;
        }
        protected void PLCCycleReset(IAutomationDriver plc)
        {
            IExecuteReader result = plc.ExecuteReader("CYCLE_REST");
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
        }
        protected object ReadPLC(IAutomationDriver plc, string address, int length)
        {
            IExecuteReader result = plc.ExecuteReader("READ", address, length);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return result.Result;
        }
        protected T ReadPLC<T>(IAutomationDriver plc, string address, int length)
        {
            IExecuteReader result = plc.ExecuteReader("READ", address, length);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return (T)result.Result;
        }
        protected object ReadPLC(IAutomationDriver plc, string address)
        {
            IExecuteReader result = plc.ExecuteReader("READ", address, 1);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return result.Result;
        }
        protected T ReadPLC<T>(IAutomationDriver plc, string address)
        {
            IExecuteReader result = plc.ExecuteReader("READ", address, 1);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return (T)result.Result;
        }

        protected bool DetectRisingEdge(IAutomationDriver plc, string address)
        {
            IExecuteReader result = plc.ExecuteReader("RISING_EDGE", address, 1);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return (bool)result.Result;
        }
        protected bool DetectFallingEdge(IAutomationDriver plc, string address)
        {
            IExecuteReader result = plc.ExecuteReader("FALLING_EDGE", address, 1);
            if (result.Success)
            {
                //TODO;
            }
            else
            {
                //TODO;
            }
            return (bool)result.Result;
        }

        private string errors = string.Empty;
        protected bool DialTablePLCError = false;
        protected bool OvenPLCError = false;
        protected Dictionary<string, MachineInformationItem> CurrentErrors = new Dictionary<string, MachineInformationItem>();
        //保存发生错误的所有工站当前NestID
        protected int[] AllStnNestID = new int[8]{0,0,0,0,0,0,0,0};
        protected bool ErrorsChangeDetected()
        {
            int stn = 0, last_stn = 0;
            StringBuilder temp = new StringBuilder();
            CurrentErrors.Clear();
            //  List<string> test = new List<string>（RuntimeDB.Errors.Keys）;
            //for (int i = 0; i < RuntimeDB.Errors.Count; i++)
            //{
            //    MachineInformationItem item = RuntimeDB.Errors.Values;
            //}
            foreach (KeyValuePair<string, MachineInformationItem> it in RuntimeDB.Errors_CN)
            {
                MachineInformationItem item = it.Value;
                if (item.Index == 999)
                {
                    item.Value = DialTablePLCError;
                }
                else if (item.Index == 1000)
                {
                    item.Value = OvenPLCError;
                }
                else
                {
                    item.Value = ReadPLC<bool>(dialTablePLC, item.Address, 1);
                }
                if (item.Value)
                {
                    CurrentErrors.Add(item.Code, item);
                    temp.Append(item.Value);
                    #region 读取站nestID
                    try
                    {
                        stn = Int32.Parse(item.Station.Substring(3, 2));
                        if (last_stn != stn)
                        {
                            last_stn = stn;
                            #region nestID
                            switch (stn)
                            {
                                case 1:
                                    AllStnNestID[0] = ReadPLC<int>(dialTablePLC, "E2800", 1);
                                    break;
                                case 2:
                                    AllStnNestID[1] = ReadPLC<int>(dialTablePLC, "E2844", 1);
                                    break;
                                case 3:
                                    AllStnNestID[2] = ReadPLC<int>(dialTablePLC, "E2858", 1);
                                    break;
                                case 4:
                                    AllStnNestID[3] = ReadPLC<int>(dialTablePLC, "E2868", 1);
                                    break;
                                case 5:
                                    AllStnNestID[4] = ReadPLC<int>(dialTablePLC, "E2878", 1);
                                    break;
                                case 6:
                                    AllStnNestID[5] = ReadPLC<int>(dialTablePLC, "E2882", 1);
                                    break;
                                case 7:
                                    AllStnNestID[6] = ReadPLC<int>(dialTablePLC, "E2882", 1);
                                    break;
                                case 8:
                                    AllStnNestID[7] = ReadPLC<int>(dialTablePLC, "E2882", 1);
                                    break;
                            }
                            #endregion
                        }
                    }
                    catch
                    {

                    }
                    #endregion
                }
            }
            if (temp.ToString() != errors)
            {
                errors = temp.ToString();
                return true;
            }
            return false;
        }
        private string conditions = string.Empty;

        protected Dictionary<string, MachineInformationItem> CurrentConditions = new Dictionary<string, MachineInformationItem>();
        protected bool ConditionsChangeDetected()
        {
            StringBuilder temp = new StringBuilder();
            CurrentConditions.Clear();
            foreach (MachineInformationItem item in RuntimeDB.Conditions_CN.Values)
            {
                item.Value = ReadPLC<bool>(dialTablePLC, item.Address, 1);
                if (item.Value)
                {
                    CurrentConditions.Add(item.Code, item);
                }
                temp.Append(item.Value);
            }
            if (temp.ToString() != conditions)
            {
                conditions = temp.ToString();
                return true;
            }
            return false;
        }
        protected void WriteError(string errorCode, bool value)
        {
            MachineInformationItem item = RuntimeDB.Errors_CN[errorCode];
            WritePLC(dialTablePLC, item.Address, 1, value);
        }
        protected void WriteCondition(string errorCode, bool value)
        {
            MachineInformationItem item = RuntimeDB.Conditions_CN[errorCode];
            WritePLC(dialTablePLC, item.Address, 1, value);
        }

        protected string PLCWordsToString(int[] words)
        {
            byte[] b_datas;
            IntArrayToBytesArray(words, out b_datas);
            string sn = Encoding.ASCII.GetString(b_datas);
            return sn;
        }
        protected void IntArrayToBytesArray(int[] indata, out byte[] outdata)
        {
            outdata = null;

            if ((indata == null) || (indata.Length == 0))
            {
                return;
            }

            outdata = new byte[indata.Length * 2];
            for (int i = 0; i < indata.Length; i++)
            {
                byte t1 = ((byte)(indata[i] / 256));
                byte t2 = ((byte)(indata[i] % 256));

                outdata[2 * i] = t1;
                outdata[2 * i + 1] = t2;
            }
        }

    }
}
